<?php
declare (strict_types=1);
// +----------------------------------------------------------------------
// | 抽奖活动
// +----------------------------------------------------------------------

namespace app\mall\controller;

use app\BaseController;
use app\mall\model\Coupon;
use app\mall\model\CouponLog;
use app\mall\model\Draw;
use app\mall\model\DrawAward;
use app\mall\model\DrawLog;
use helper\algorithm\Probability;
use think\exception\ValidateException;
use think\facade\Cache;

class DrawController extends BaseController
{
    /**
     * @OA\Get(path="/draw",tags={"抽奖"},summary="列表",
     *   @OA\Parameter(name="authorization", in="header", description="Bearer token", @OA\Schema(type="string")),
     *   @OA\Parameter(name="page", in="query", description="页码", @OA\Schema(type="int", default="1")),
     *   @OA\Parameter(name="limit", in="query", description="行数", @OA\Schema(type="int", default="10")),
     *   @OA\Parameter(name="type", in="query", description="类型", @OA\Schema(type="int", default="10")),
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function index()
    {
        $param = $this->request->param();
        $field = $param['field'] ?? 'id';
        $order = $param['order'] ?? 'desc';
        $limit = $param['limit'] ?? 10;

        $where = [];
        if (isset($param['keyword'])) {
            $where[] = ['name', 'like', '%' . $param['keyword'] . '%'];
        }
        if (isset($param['type'])) {
            $where[] = ['type', '=', $param['type']];
        }
        if (isset($param['status'])) {
            $where[] = ['status', '=', $param['status']];
        }

        $list  = Draw::with('award')
            ->where($where)
            ->order($field, $order)
            ->paginate($limit);
        $count = $list->total();
        $list  = $list->items();
        $this->success('获取成功', compact('list', 'count'));
    }

    /**
     * @OA\Post(path="/draw",tags={"抽奖"},summary="新增",
     *   @OA\Parameter(name="authorization", in="header", description="Bearer token", @OA\Schema(type="string")),
     *   @OA\RequestBody(
     *     @OA\MediaType(mediaType="multipart/form-data",
     *         @OA\Schema(
     *          @OA\Property(description="活动类型", property="type", type="integer"),
     *           @OA\Property(description="活动名称", property="name", type="string"),
     *           @OA\Property(description="活动详情", property="content", type="string"),
     *           @OA\Property(description="开始时间", property="start_time", type="string"),
     *           @OA\Property(description="结束时间", property="end_time", type="number"),
     *           @OA\Property(description="参与类型", property="join_type", type="number"),
     *           @OA\Property(description="参与次数", property="join_count", type="number"),
     *           @OA\Property(description="消耗积分", property="points", type="integer"),
     *           @OA\Property(description="未中奖说明", property="failed", type="string"),
     *           @OA\Property(description="奖品设置[type,coupon_id,number,probability]", property="award", type="json"),
     *           required={"type","name","content","start_time","end_time","join_type","join_count","award"})
     *       )
     *     ),
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function save()
    {
        $param = $this->request->param();
        $this->validate($param, 'app\mall\validate\Draw');
        $draw = Draw::create($param);
        $data = $draw->award()->saveAll($param['award']);
        if (!$data) {
            throw new ValidateException("保存失败");
        }
        $this->success('保存成功', $data);
    }

    /**
     * @OA\Get(path="/draw/{id}",tags={"抽奖"},summary="详情",
     *   @OA\Parameter(name="id", in="path", description="id", @OA\Schema(type="int")),
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function read($id)
    {
        $data = Draw::with('award')->find($id);
        $this->success('获取成功', $data);
    }

    /**
     * @OA\Put(path="/draw/{id}",tags={"抽奖"},summary="编辑",
     *   @OA\Parameter(name="authorization", in="header", description="Bearer token", @OA\Schema(type="string")),
     *   @OA\Parameter(name="id", in="path", description="id", @OA\Schema(type="int")),
     *   @OA\RequestBody(
     *     @OA\MediaType(mediaType="multipart/form-data",
     *         @OA\Schema(
     *          @OA\Property(description="活动类型", property="type", type="integer"),
     *           @OA\Property(description="活动名称", property="name", type="string"),
     *           @OA\Property(description="活动详情", property="content", type="string"),
     *           @OA\Property(description="开始时间", property="start_time", type="string"),
     *           @OA\Property(description="结束时间", property="end_time", type="number"),
     *           @OA\Property(description="参与次数", property="total", type="number"),
     *           @OA\Property(description="消耗积分", property="points", type="integer"),
     *           @OA\Property(description="未中奖说明", property="failed", type="string"),
     *           @OA\Property(description="奖品设置[id,type,draw_id,number,probability]", property="award", type="json"),
     *           required={"type","name","content","start_time","end_time","total","award"})
     *       )
     *     ),
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function update($id)
    {
        $param = $this->request->param();
        $draw  = Draw::find($id);
        if (!$draw) {
            throw new ValidateException("信息错误");
        }
        $this->validate($param, 'app\mall\validate\Draw');
        $draw->save($param);
        $draw['award'] = $draw->award()->saveAll($param['award']);
        $this->success('保存成功', $draw);
    }

    /**
     * @OA\Delete(path="/draw/{id}",tags={"抽奖"},summary="删除",
     *   @OA\Parameter(name="authorization", in="header", description="Bearer token", @OA\Schema(type="string")),
     *   @OA\Parameter(name="id", in="path", description="id", @OA\Schema(type="int")),
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function delete($id)
    {
        $draw = Draw::with('comments')->find($id);
        $res  = $draw->together(['award'])->delete();
        if (!$res) {
            $this->error("删除失败");
        }
        $this->success('删除成功');
    }

    /**
     * @OA\Post(path="/draw/join",tags={"抽奖"},summary="新增",
     *   @OA\Parameter(name="authorization", in="header", description="Bearer token", @OA\Schema(type="string")),
     *   @OA\RequestBody(
     *     @OA\MediaType(mediaType="multipart/form-data",
     *         @OA\Schema(
     *           @OA\Property(description="抽奖id", property="id", type="string"),
     *           required={"id"})
     *       )
     *     ),
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function join()
    {
        $id   = $this->request->param('id', 0);
        $draw = Draw::with('award')->find($id);
        if (!$draw) {
            $this->error('活动不存在');
        }

        switch ($draw['type']) {
            case 5:
                $this->type5($draw);
                break;
        }
    }

    /**
     * 刮刮卡
     * @param $draw
     */
    public function type1($draw)
    {
        $prize_arr = [];
        $weight    = [];
        foreach ($prize_arr as $val) {
            $weight[$val['id']] = $val['probability'];
        }
        $probability = new Probability();
        $rand = $probability->get_rand($weight);//根据概率获取奖项id
        $rid = $rand['id'];
        $res['yes'] = $prize_arr[$rid - 1]['prize'];//中奖项
        unset($prize_arr[$rid - 1]);//将中奖项从数组中剔除，剩下未中奖项
        shuffle($prize_arr);//打乱数组顺序

        // 未中奖
        $pr = [];
        for ($i = 0; $i < count($prize_arr); $i++) {
            $pr[] = $prize_arr[$i]['prize'];
        }
        $res['no'] = $pr;
    }

    /**
     * 大转盘
     * @param $draw
     */
    public function type2($draw)
    {

    }

    /**
     * 砸金蛋
     * @param $draw
     */
    public function type3($draw)
    {

    }

    /**
     * 生肖翻翻看
     * @param $draw
     */
    public function type4($draw)
    {

    }

    /**
     * 分享得优惠券
     * @param $draw
     */
    public function type5($draw)
    {
        $redis     = Cache::store('redis')->handler();
        $key       = 'share:' . $this->user_id;
        $offset    = (int)date('Ymd');

        //查询今天情况
        $bitStatus = $redis->getBit($key, $offset);
        if ($bitStatus) {
            $this->error('今日已分享');
        }

        $redis->setBit($key, $offset, true);

        //计算总次数
        $count = $redis->bitCount($key);
        $msg   = '分享成功';
        if ($count % 3 == 0) {
            // 奖项数组
            $prize_arr = $draw->award;
            $weight    = [];
            foreach ($prize_arr as $val) {
                $weight[$val['id']] = $val['probability'];
            }

            $probability = new Probability();
            $draw_award_id = $probability->get_rand($weight);
            $draw_award    = DrawAward::with('coupon')->find($draw_award_id);

            // 抽奖记录
            DrawLog::create([
                'user_id'       => $this->user_id,
                'user_name'     => $this->user->name,
                'draw_id'       => $draw->id,
                'draw_award_id' => $draw_award_id,
                'status'        => 1
            ]);

            // 优惠券
            Coupon::where('id', $draw->id)->inc('receive_count')->update();

            // 优惠券记录
            CouponLog::create([
                'user_id'     => $this->user_id,
                'coupon_id'   => $draw_award->coupon->id,
                'title'       => $draw_award->coupon->title,
                'desc'        => $draw_award->coupon->desc,
                'start_date'  => $draw_award->coupon->start_date,
                'end_date'    => $draw_award->coupon->end_date,
                'price'       => $draw_award->coupon->price,
                'price_limit' => $draw_award->coupon->price_limit,
            ]);
            $msg = '优惠券已发放,请前往商超-我的-优惠券查收';
        }
        $this->success($msg, ['count' => $count]);
    }
}